{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 计算项目活跃度"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import os\n",
    "import glob\n",
    "import numpy as np\n",
    "import pandas as pd\n",
    "import ast \n",
    "import statistics\n",
    "from datetime import datetime \n",
    "\n",
    "def get_prefix_from_path(file_path):\n",
    "    if not file_path:\n",
    "        return 'default'\n",
    "\n",
    "    base_name = os.path.splitext(os.path.basename(file_path))[0]\n",
    "    parts = base_name.split('_')\n",
    "    \n",
    "    if len(parts) >= 2:\n",
    "        return '_'.join(parts[:2])\n",
    "    else:\n",
    "        return base_name\n",
    "\n",
    "def activity(input_file_path1,input_file_path2,input_file_path3,input_file_path4,input_file_path5,prefix):\n",
    "\n",
    "    df=pd.read_csv('activity.csv')\n",
    "    df_extra=pd.read_csv('death.csv')\n",
    "    df_size=pd.read_csv('size.csv')\n",
    "    df=pd.DataFrame(df)\n",
    "    df_extra=pd.DataFrame(df_extra)\n",
    "    df_size=pd.DataFrame(df_size)\n",
    "    #采用contributor busfactor inact new\n",
    "    #bus不可失去即核心\n",
    "    # 防止没有搜寻到路径，则将该方面评分设置为0\n",
    "    data_con = pd.read_csv(input_file_path1)['指标值'] if input_file_path1 else np.zeros(300, dtype=int)\n",
    "    data_bus = pd.read_csv(input_file_path2)['指标值'] if input_file_path2 else np.zeros(300, dtype=int)\n",
    "    data_new = pd.read_csv(input_file_path3)['指标值'] if input_file_path3 else np.zeros(300, dtype=int)\n",
    "    data_inact = pd.read_csv(input_file_path4)['指标值'] if input_file_path4 else np.zeros(300, dtype=int)\n",
    "    data_part = pd.read_csv(input_file_path5)['指标值'] if input_file_path5 else np.zeros(300, dtype=int)\n",
    "\n",
    "    part_max=data_part.max()\n",
    "\n",
    "    if part_max < 10 :\n",
    "        size =1\n",
    "    elif part_max < 100 :\n",
    "        size =2\n",
    "    elif part_max <1000 :\n",
    "        size =3\n",
    "    elif part_max <10000 :\n",
    "        size =4\n",
    "    else :\n",
    "        size =5\n",
    "\n",
    "    row_exists=(df_size['指标名称']==prefix).any()\n",
    "\n",
    "    if row_exists:\n",
    "        df_size.loc[df_size['指标名称'] == prefix, '指标值']=size\n",
    "    # 保存更改回 CSV 文件\n",
    "    df_size.to_csv('size.csv', index=False)\n",
    "\n",
    "    death_time=0\n",
    "    data_part_live=[]\n",
    "    data_bus_live=[]\n",
    "    data_con_live=[]\n",
    "    data_inact_live=[]\n",
    "    data_new_live=[]\n",
    "    for i in range(len(data_part)) :\n",
    "        if (data_part[i]/part_max) < 0.1:\n",
    "            death_time+=1\n",
    "        else:\n",
    "            data_part_live.append(data_part[i])\n",
    "            data_bus_live.append(data_bus[i])\n",
    "            data_con_live.append(data_con[i])\n",
    "            data_inact_live.append(data_inact[i])\n",
    "            data_new_live.append(data_new[i])\n",
    "    # 计算 extra\n",
    "    death=death_time/len(data_part)\n",
    "    row_exists=(df_extra['指标名称']==prefix).any()\n",
    "\n",
    "    if row_exists:\n",
    "        df_extra.loc[df_extra['指标名称'] == prefix, '指标值']=death*10\n",
    "    # 保存更改回 CSV 文件\n",
    "    df_extra.to_csv('death.csv', index=False)\n",
    "\n",
    "\n",
    "    s_con=[]\n",
    "    s_bus=[]\n",
    "    s_new=[]\n",
    "    s_inact=[]\n",
    "\n",
    "    for i in range(len(data_con_live)): \n",
    "        if data_bus_live[i]!=0:\n",
    "            s_con.append(data_con_live[i]/data_bus_live[i])        # 贡献者 占总人数的比例\n",
    "        else:\n",
    "            s_con.append(0)\n",
    "        if data_part_live[i]!=0:\n",
    "            s_bus.append(data_bus_live[i]/data_part_live[i])       # bus_factor 占总参与人数的比例\n",
    "            s_new.append(data_new_live[i]/data_part_live[i])       # 新贡献者 占总人数的比例\n",
    "            s_inact.append(data_inact_live[i]/data_part_live[i])   # 不活跃的贡献者 占总人数的比例\n",
    "        else:\n",
    "            s.bus.append(0)\n",
    "            s_new.append(0)\n",
    "            s_inact.append(0)\n",
    "\n",
    "    avg1=np.mean(s_bus)\n",
    "    avg2=np.mean(s_inact)\n",
    "    avg3=np.mean(s_new)\n",
    "    avg4=np.mean(s_con)\n",
    "    avg5=1-avg2\n",
    "    avg6=1-avg1\n",
    "    if avg5<0:\n",
    "        avg5=0\n",
    "    if avg6<0:\n",
    "        avg6=0\n",
    "    final=avg6/6+avg3/6+avg5/6+avg4/2\n",
    "    #print(final)\n",
    "    # 获取仓库名\n",
    "    row_exists=(df['指标名称']==prefix).any()\n",
    "\n",
    "    if row_exists:\n",
    "        df.loc[df['指标名称'] == prefix, '指标值']=final*10\n",
    "\n",
    "    # 保存更改回 CSV 文件\n",
    "    df.to_csv('activity.csv', index=False)\n",
    "\n",
    "def time(input_file_path10,input_file_path5,prefix):\n",
    "\n",
    "    df_time=pd.read_csv('time.csv')\n",
    "    df_time=pd.DataFrame(df_time)\n",
    "\n",
    "    data_active=pd.read_csv(input_file_path10)['指标值']\n",
    "    data_part = pd.read_csv(input_file_path5)['指标值'] if input_file_path5 else np.zeros(300, dtype=int)\n",
    "\n",
    "    death_time=0\n",
    "    data_part_live=[]\n",
    "    data_active_live=[]\n",
    "    part_max=data_part.max()\n",
    "    for i in range(len(data_part)):\n",
    "        if (data_part[i]/part_max) < 0.1:\n",
    "            death_time+=1\n",
    "        else:\n",
    "            data_part_live.append(data_part[i])\n",
    "            data_active_live.append(data_active[i])\n",
    "\n",
    "    s_sum=[]\n",
    "    s_grade=[]\n",
    "\n",
    "    for i in range(len(data_active_live)):\n",
    "        s_data=ast.literal_eval(data_active_live[i])\n",
    "        s_sum.append(np.sum(s_data))\n",
    "        s_grade.append(10*s_sum[i]/600)\n",
    "\n",
    "    avg=np.mean(s_grade)\n",
    "    row_exists=(df_time['指标名称']==prefix).any()\n",
    "\n",
    "    if row_exists:\n",
    "        df_time.loc[df_time['指标名称'] == prefix, '指标值']=avg\n",
    "\n",
    "    # 保存更改回 CSV 文件\n",
    "    df_time.to_csv('time.csv', index=False)\n",
    "\n",
    "def request(input_file_path6,input_file_path7,input_file_path8,input_file_path9,prefix):\n",
    "\n",
    "    df=pd.read_csv('request.csv')\n",
    "    df=pd.DataFrame(df)\n",
    "\n",
    "    df_dura = pd.read_csv(input_file_path6) if input_file_path6 else np.zeros(300, dtype=int)\n",
    "    df_respontime =pd.read_csv(input_file_path7) if input_file_path7 else np.zeros(300, dtype=int)\n",
    "    df_request=pd.read_csv(input_file_path8)['指标值'] if input_file_path8 else np.zeros(300, dtype=int)\n",
    "    df_accepted=pd.read_csv(input_file_path9)['指标值'] if input_file_path9 else np.zeros(300, dtype=int)\n",
    "\n",
    "    data_request=[]\n",
    "    data_accepted=[]\n",
    "    for i in range(len(df_request)):\n",
    "        data_request.append(df_request[i].item())\n",
    "    for i in range(len(df_accepted)):\n",
    "        data_accepted.append(df_accepted[i].item())\n",
    "\n",
    "    if(input_file_path6):\n",
    "        data_dura=ast.literal_eval(df_dura['指标值'][0])\n",
    "        data_respontime=ast.literal_eval(df_respontime['指标值'][0])\n",
    "\n",
    "        times_floats=[]\n",
    "        for key, value in data_dura.items():\n",
    "            if isinstance(key, str) and len(key) == 7 and key[4] == '-':  # 简单检查是否为YYYY-MM格式\n",
    "                try:\n",
    "                    # 将字符串时间转换为datetime对象\n",
    "                    date_obj = datetime.strptime(key, '%Y-%m')\n",
    "                    # 尝试将值转换为float\n",
    "                    float_value = float(value)\n",
    "                    times_floats.append((date_obj, float_value))\n",
    "                except (ValueError, TypeError):\n",
    "                    # 如果转换失败，跳过该项\n",
    "                    continue\n",
    "        # 按照日期排序\n",
    "        times_floats.sort(key=lambda x: x[0])\n",
    "        # 分离时间和值到两个独立的列表中\n",
    "        dates_dura, values_dura = zip(*times_floats) if times_floats else ([], [])\n",
    "        \n",
    "        # 过滤并转换时间和值\n",
    "        times_floats = []\n",
    "\n",
    "        for key, value in data_respontime.items():\n",
    "            if isinstance(key, str) and len(key) == 7 and key[4] == '-':  # 简单检查是否为YYYY-MM格式\n",
    "                try:\n",
    "                    # 将字符串时间转换为datetime对象\n",
    "                    date_obj = datetime.strptime(key, '%Y-%m')\n",
    "                    # 尝试将值转换为float\n",
    "                    float_value = float(value)\n",
    "                    times_floats.append((date_obj, float_value))\n",
    "                except (ValueError, TypeError):\n",
    "                    # 如果转换失败，跳过该项\n",
    "                    continue\n",
    "\n",
    "        # 按照日期排序\n",
    "        times_floats.sort(key=lambda x: x[0])\n",
    "        # 分离时间和值到两个独立的列表中\n",
    "        dates_respontime, values_respontime = zip(*times_floats) if times_floats else ([], [])\n",
    "\n",
    "        s_value_dura=[]\n",
    "        s_value_respontime=[]\n",
    "        for i in range(len(values_dura)):\n",
    "            if values_dura[i]>10 :\n",
    "                s_value_dura.append(10)\n",
    "            else:\n",
    "                s_value_dura.append(values_dura[i])\n",
    "        for i in range(len(values_respontime)):\n",
    "            if values_respontime[i]>20 :\n",
    "                s_value_respontime.append(20)\n",
    "            else:\n",
    "                s_value_respontime.append(values_respontime[i])\n",
    "        avg2=np.mean(s_value_respontime)\n",
    "        avg3=np.mean(s_value_dura)    \n",
    "    else:\n",
    "        avg2=20\n",
    "        avg3=10\n",
    "\n",
    "\n",
    "    s_request=[]\n",
    "    for i in range(len(data_request)):\n",
    "        if data_request[i]!=0 :\n",
    "            s_request.append(data_accepted[i]/data_request[i])\n",
    "        else :\n",
    "            s_request.append(0)\n",
    "    avg1=np.mean(s_request)\n",
    "    avg4=20-avg2\n",
    "    avg5=10-avg3\n",
    "    if avg4 < 0:\n",
    "        avg4=0\n",
    "    if avg5 < 0 :\n",
    "        avg5=0\n",
    "    \n",
    "    final=(avg1*10+avg4/2+avg5)/3\n",
    "    # 获取仓库名\n",
    "    row_exists=(df['指标名称']==prefix).any()\n",
    "\n",
    "    if row_exists:\n",
    "        df.loc[df['指标名称'] == prefix, '指标值']=final\n",
    "\n",
    "    # 保存更改回 CSV 文件\n",
    "    df.to_csv('request.csv', index=False)\n",
    "\n",
    "\n",
    "def get_prefix_and_rest(filename):\n",
    "\n",
    "    base_name = os.path.basename(filename)\n",
    "    # 分离文件名和扩展名\n",
    "    name_part, ext_part = os.path.splitext(base_name) \n",
    "    # 按下划线分割文件名部分，并确保至少有两个'_'\n",
    "    parts = name_part.split('_')\n",
    "\n",
    "    if len(parts) > 1:\n",
    "        # 获取前两个'_'之间的部分作为前缀\n",
    "        prefix = '_'.join(parts[:2])\n",
    "        # 剩余部分加上原始扩展名作为后缀\n",
    "        rest = '_'.join(parts[2:]) + ext_part if len(parts) > 2 else ext_part\n",
    "    else:\n",
    "        # 如果没有足够的'_'，则返回整个文件名作为前缀，空字符串作为后缀\n",
    "        prefix = name_part\n",
    "        rest = ext_part\n",
    "    \n",
    "    return prefix, rest\n",
    "\n",
    "def process_files_with_same_prefix(base_dir):\n",
    "    # 定义需要查找的文件后缀\n",
    "    file_suffixes = [\n",
    "        'contributor.csv', 'bus_factor.csv', 'new_contributors.csv',\n",
    "        'inactive_contributors.csv', 'participants.csv',\n",
    "        'change_request_resolution_duration.csv',\n",
    "        'change_request_response_time.csv', 'change_requests.csv',\n",
    "        'change_requests_accepted.csv','active_dates_and_times.csv'\n",
    "    ]\n",
    "    \n",
    "    # 获取所有csv文件\n",
    "    all_files = glob.glob(os.path.join(base_dir, '*.csv'))\n",
    "    # 创建一个字典来存储每个前缀对应的文件路径列表\n",
    "    files_dict = {}\n",
    "    \n",
    "    for file in all_files:\n",
    "        \n",
    "        # 获取仓库和后缀的部分作为前缀\n",
    "        prefix, suffix = get_prefix_and_rest(os.path.basename(file))\n",
    "        \n",
    "        key = next((s for s in file_suffixes if s==suffix), None)\n",
    "        if key:  # prefix是仓库名，key是文件后缀匹配，file是路径\n",
    "            if prefix not in files_dict:\n",
    "                files_dict[prefix] = {}\n",
    "            files_dict[prefix][key] = file\n",
    "    # 遍历字典并调用activity函数\n",
    "    for prefix, paths in files_dict.items():\n",
    "        # 调用 activity 函数，传递对应前缀的所有文件路径\n",
    "        input_file_path1=paths.get('contributor.csv')\n",
    "        input_file_path2=paths.get('bus_factor.csv')\n",
    "        input_file_path3=paths.get('new_contributors.csv')\n",
    "        input_file_path4=paths.get('inactive_contributors.csv')\n",
    "        input_file_path5=paths.get('participants.csv')\n",
    "        input_file_path6=paths.get('change_request_resolution_duration.csv')\n",
    "        input_file_path7=paths.get('change_request_response_time.csv')\n",
    "        input_file_path8=paths.get('change_requests.csv')            \n",
    "        input_file_path9=paths.get('change_requests_accepted.csv')\n",
    "        input_file_path10=paths.get('active_dates_and_times.csv')\n",
    "        activity(input_file_path1,input_file_path2,input_file_path3,input_file_path4,input_file_path5,prefix)\n",
    "        time(input_file_path10,input_file_path5,prefix)\n",
    "        request(input_file_path6,input_file_path7,input_file_path8,input_file_path9,prefix)\n",
    "\n",
    "# 假设 base_dir 是你的文件夹路径\n",
    "base_dir='./最终数据处理'\n",
    "process_files_with_same_prefix(base_dir)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 计算社区参与度"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import os\n",
    "import glob\n",
    "import numpy as np\n",
    "import pandas as pd\n",
    "import ast \n",
    "import statistics\n",
    "from datetime import datetime \n",
    "\n",
    "def get_prefix_from_path(file_path):\n",
    "    if not file_path:\n",
    "        return 'default'\n",
    "\n",
    "    base_name = os.path.splitext(os.path.basename(file_path))[0]\n",
    "    parts = base_name.split('_')\n",
    "    \n",
    "    if len(parts) >= 2:\n",
    "        return '_'.join(parts[:2])\n",
    "    else:\n",
    "        return base_name\n",
    "\n",
    "def issue(input_file_path1,input_file_path2,input_file_path3,input_file_path4,input_file_path5,prefix):\n",
    "\n",
    "    df=pd.read_csv('issue.csv')\n",
    "    df=pd.DataFrame(df)\n",
    "\n",
    "    data_comment = pd.read_csv(input_file_path1)['指标值'] if input_file_path1 else np.zeros(300, dtype=int)\n",
    "    data_dura = pd.read_csv(input_file_path2)['指标值']  if input_file_path2 else np.zeros(300, dtype=int)\n",
    "    data_respontime = pd.read_csv(input_file_path3)['指标值'] if input_file_path3 else np.zeros(300, dtype=int)\n",
    "    data_new = pd.read_csv(input_file_path4)['指标值'] if input_file_path4 else np.zeros(300, dtype=int)\n",
    "    data_closed = pd.read_csv(input_file_path5)['指标值'] if input_file_path5 else np.zeros(300, dtype=int)\n",
    "    \n",
    "    if input_file_path2:\n",
    "\n",
    "        data_duration=ast.literal_eval(data_dura[0])\n",
    "\n",
    "        # 过滤并转换时间和值\n",
    "        times_floats = []\n",
    "        for key, value in data_duration.items():\n",
    "            if isinstance(key, str) and len(key) == 7 and key[4] == '-':  # 简单检查是否为YYYY-MM格式\n",
    "                try:\n",
    "                    # 将字符串时间转换为datetime对象\n",
    "                    date_obj = datetime.strptime(key, '%Y-%m')\n",
    "                    # 尝试将值转换为float\n",
    "                    float_value = float(value)\n",
    "                    times_floats.append((date_obj, float_value))\n",
    "                except (ValueError, TypeError):\n",
    "                    # 如果转换失败，跳过该项\n",
    "                    continue\n",
    "        # 按照日期排序\n",
    "        times_floats.sort(key=lambda x: x[0])\n",
    "        # 分离时间和值到两个独立的列表中\n",
    "        dates_duration, values_duration = zip(*times_floats) if times_floats else ([], [])\n",
    "       \n",
    "        s_duration=[]\n",
    "        \n",
    "        for i in range(len(values_duration)):\n",
    "            if values_duration[i]>10 :\n",
    "                s_duration.append(10)\n",
    "            else:\n",
    "                s_duration.append(values_duration[i])\n",
    "        avg4=np.mean(s_duration)\n",
    "    else :\n",
    "        avg4=0    \n",
    "       \n",
    "    if input_file_path3:\n",
    "        data_response=ast.literal_eval(data_respontime[0]) \n",
    "        times_floats = []\n",
    "        for key, value in data_response.items():\n",
    "            if isinstance(key, str) and len(key) == 7 and key[4] == '-':  # 简单检查是否为YYYY-MM格式\n",
    "                try:\n",
    "                    # 将字符串时间转换为datetime对象\n",
    "                    date_obj = datetime.strptime(key, '%Y-%m')\n",
    "                    # 尝试将值转换为float\n",
    "                    float_value = float(value)\n",
    "                    times_floats.append((date_obj, float_value))\n",
    "                except (ValueError, TypeError):\n",
    "                    # 如果转换失败，跳过该项\n",
    "                    continue\n",
    "        # 按照日期排序\n",
    "        times_floats.sort(key=lambda x: x[0])\n",
    "        # 分离时间和值到两个独立的列表中\n",
    "        dates_response, values_response = zip(*times_floats) if times_floats else ([], [])\n",
    "        s_response=[]\n",
    "        for i in range(len(values_response)):\n",
    "                if values_response[i]>20 :\n",
    "                    s_response.append(20)\n",
    "                else:\n",
    "                    s_response.append(values_response[i]) \n",
    "        avg3=np.mean(s_response)\n",
    "        avg3=avg3/2\n",
    "    else:\n",
    "        avg3=0\n",
    "\n",
    "    s_closed=[]\n",
    "    s_new=[]\n",
    "   \n",
    "    for i in range(len(data_comment)):\n",
    "        if data_comment[i]!=0:\n",
    "            s_closed.append(data_closed[i]/data_comment[i])\n",
    "            s_new.append(data_new[i]/data_comment[i])\n",
    "        else:\n",
    "            s_closed.append(0)\n",
    "            s_new.append(0)\n",
    "\n",
    "    avg1=np.mean(s_closed)\n",
    "    avg2=np.mean(s_new)\n",
    "\n",
    "    final=avg1*10/6+avg2*10/3+avg3/4+avg4/4\n",
    "\n",
    "    # 获取仓库名\n",
    "    row_exists=(df['指标名称']==prefix).any()\n",
    "\n",
    "    if row_exists:\n",
    "        df.loc[df['指标名称'] == prefix, '指标值']=final\n",
    "\n",
    "    # 保存更改回 CSV 文件\n",
    "    df.to_csv('issue.csv', index=False)\n",
    "\n",
    "def get_prefix_and_rest(filename):\n",
    "\n",
    "    base_name = os.path.basename(filename)\n",
    "    # 分离文件名和扩展名\n",
    "    name_part, ext_part = os.path.splitext(base_name) \n",
    "    # 按下划线分割文件名部分，并确保至少有两个'_'\n",
    "    parts = name_part.split('_')\n",
    "\n",
    "    if len(parts) > 1:\n",
    "        # 获取前两个'_'之间的部分作为前缀\n",
    "        prefix = '_'.join(parts[:2])\n",
    "        # 剩余部分加上原始扩展名作为后缀\n",
    "        rest = '_'.join(parts[2:]) + ext_part if len(parts) > 2 else ext_part\n",
    "    else:\n",
    "        # 如果没有足够的'_'，则返回整个文件名作为前缀，空字符串作为后缀\n",
    "        prefix = name_part\n",
    "        rest = ext_part\n",
    "    \n",
    "    return prefix, rest\n",
    "\n",
    "def process_files_with_same_prefix(base_dir):\n",
    "    # 定义需要查找的文件后缀\n",
    "    file_suffixes = [\n",
    "        'issue_comments.csv','issue_resolution_duration.csv','issue_response_time.csv',\n",
    "        'issues_new.csv','issues_closed.csv'\n",
    "    ]\n",
    "    \n",
    "    # 获取所有csv文件\n",
    "    all_files = glob.glob(os.path.join(base_dir, '*.csv'))\n",
    "    # 创建一个字典来存储每个前缀对应的文件路径列表\n",
    "    files_dict = {}\n",
    "    \n",
    "    for file in all_files:\n",
    "        \n",
    "        # 获取仓库和后缀的部分作为前缀\n",
    "        prefix, suffix = get_prefix_and_rest(os.path.basename(file))\n",
    "        \n",
    "        key = next((s for s in file_suffixes if s==suffix), None)\n",
    "        if key:  # prefix是仓库名，key是文件后缀匹配，file是路径\n",
    "            if prefix not in files_dict:\n",
    "                files_dict[prefix] = {}\n",
    "            files_dict[prefix][key] = file\n",
    "    # 遍历字典并调用activity函数\n",
    "    for prefix, paths in files_dict.items():\n",
    "        # 调用 activity 函数，传递对应前缀的所有文件路径\n",
    "        input_file_path1=paths.get('issue_comments.csv')\n",
    "        input_file_path2=paths.get('issue_resolution_duration.csv')\n",
    "        input_file_path3=paths.get('issue_response_time.csv')\n",
    "        input_file_path4=paths.get('issues_new.csv')\n",
    "        input_file_path5=paths.get('issues_closed.csv')\n",
    "        issue(input_file_path1,input_file_path2,input_file_path3,input_file_path4,input_file_path5,prefix)\n",
    "\n",
    "# 假设 base_dir 是你的文件夹路径\n",
    "base_dir='./最终数据处理'\n",
    "process_files_with_same_prefix(base_dir)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 计算代码质量"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import os\n",
    "import glob\n",
    "import numpy as np\n",
    "import pandas as pd\n",
    "import ast \n",
    "import statistics\n",
    "from datetime import datetime \n",
    "\n",
    "def get_prefix_from_path(file_path):\n",
    "    if not file_path:\n",
    "        return 'default'\n",
    "\n",
    "    base_name = os.path.splitext(os.path.basename(file_path))[0]\n",
    "    parts = base_name.split('_')\n",
    "    \n",
    "    if len(parts) >= 2:\n",
    "        return '_'.join(parts[:2])\n",
    "    else:\n",
    "        return base_name\n",
    "\n",
    "def quality(input_file_path1,input_file_path2,input_file_path3,input_file_path4,input_file_path5,input_file_path6,prefix):\n",
    "\n",
    "    df=pd.read_csv('quality.csv')\n",
    "    df=pd.DataFrame(df)\n",
    "\n",
    "    data_add = pd.read_csv(input_file_path1)['指标值'] if input_file_path1 else np.zeros(300, dtype=int)\n",
    "    data_remove = pd.read_csv(input_file_path2)['指标值'] if input_file_path2 else np.zeros(300, dtype=int)\n",
    "    data_sum = pd.read_csv(input_file_path3)['指标值'] if input_file_path3 else np.zeros(300, dtype=int)\n",
    "    data_review = pd.read_csv(input_file_path4)['指标值'] if input_file_path4 else np.zeros(300, dtype=int)\n",
    "    data_request = pd.read_csv(input_file_path5)['指标值'] if input_file_path5 else np.zeros(300, dtype=int)\n",
    "    data_accepted = pd.read_csv(input_file_path6)['指标值'] if input_file_path6 else np.zeros(300, dtype=int)\n",
    "\n",
    "\n",
    "    sum_request=sum(data_request)\n",
    "    sum_review=sum(data_review)\n",
    "    if(sum_request!=0):\n",
    "        avg1=sum_review/sum_request\n",
    "    else :\n",
    "        avg1=0\n",
    "    s_request=[]\n",
    "    for i in range(len(data_request)) :\n",
    "        if data_request[i]!=0:\n",
    "            s_request.append(data_accepted[i]/data_request[i])\n",
    "        else:\n",
    "            s_request.append(0)\n",
    "    avg2=np.mean(s_request)\n",
    "\n",
    "    s_add=[]\n",
    "    s_remove=[]\n",
    "    for i in range(len(data_sum)):\n",
    "        if data_sum[i]!=0:\n",
    "            s_add.append(data_add[i]/np.abs(data_sum[i]))\n",
    "            s_remove.append(data_remove[i]/np.abs(data_sum[i]))\n",
    "        else :\n",
    "            s_add.append(0)\n",
    "            s_remove.append(0)\n",
    "    avg3=np.mean(s_add)\n",
    "    avg4=np.mean(s_remove)\n",
    "    avg5=avg3-avg4\n",
    "    final=avg1/4+avg2/4+abs(avg5/2)\n",
    "    # 获取仓库名\n",
    "    row_exists=(df['指标名称']==prefix).any()\n",
    "\n",
    "    if row_exists:\n",
    "        df.loc[df['指标名称'] == prefix, '指标值']=final*10\n",
    "\n",
    "    # 保存更改回 CSV 文件\n",
    "    df.to_csv('quality.csv', index=False)\n",
    "\n",
    "def get_prefix_and_rest(filename):\n",
    "\n",
    "    base_name = os.path.basename(filename)\n",
    "    # 分离文件名和扩展名\n",
    "    name_part, ext_part = os.path.splitext(base_name) \n",
    "    # 按下划线分割文件名部分，并确保至少有两个'_'\n",
    "    parts = name_part.split('_')\n",
    "\n",
    "    if len(parts) > 1:\n",
    "        # 获取前两个'_'之间的部分作为前缀\n",
    "        prefix = '_'.join(parts[:2])\n",
    "        # 剩余部分加上原始扩展名作为后缀\n",
    "        rest = '_'.join(parts[2:]) + ext_part if len(parts) > 2 else ext_part\n",
    "    else:\n",
    "        # 如果没有足够的'_'，则返回整个文件名作为前缀，空字符串作为后缀\n",
    "        prefix = name_part\n",
    "        rest = ext_part\n",
    "    \n",
    "    return prefix, rest\n",
    "\n",
    "def process_files_with_same_prefix(base_dir):\n",
    "    # 定义需要查找的文件后缀\n",
    "    file_suffixes = [\n",
    "        'code_change_lines_add.csv','code_change_lines_remove.csv','code_change_lines_sum.csv',\n",
    "        'change_requests_reviews.csv','change_requests.csv','change_requests_accepted.csv',\n",
    "        'active_dates_and_times.csv'\n",
    "    ]\n",
    "    \n",
    "    # 获取所有csv文件\n",
    "    all_files = glob.glob(os.path.join(base_dir, '*.csv'))\n",
    "    # 创建一个字典来存储每个前缀对应的文件路径列表\n",
    "    files_dict = {}\n",
    "    \n",
    "    for file in all_files:\n",
    "        \n",
    "        # 获取仓库和后缀的部分作为前缀\n",
    "        prefix, suffix = get_prefix_and_rest(os.path.basename(file))\n",
    "        \n",
    "        key = next((s for s in file_suffixes if s==suffix), None)\n",
    "        if key:  # prefix是仓库名，key是文件后缀匹配，file是路径\n",
    "            if prefix not in files_dict:\n",
    "                files_dict[prefix] = {}\n",
    "            files_dict[prefix][key] = file\n",
    "    # 遍历字典并调用activity函数\n",
    "    for prefix, paths in files_dict.items():\n",
    "        # 调用 activity 函数，传递对应前缀的所有文件路径\n",
    "        input_file_path1=paths.get('code_change_lines_add.csv')\n",
    "        input_file_path2=paths.get('code_change_lines_remove.csv')\n",
    "        input_file_path3=paths.get('code_change_lines_sum.csv')\n",
    "        input_file_path4=paths.get('change_requests_reviews.csv')\n",
    "        input_file_path5=paths.get('change_requests.csv')\n",
    "        input_file_path6=paths.get('change_requests_accepted.csv')\n",
    "\n",
    "        quality(input_file_path1,input_file_path2,input_file_path3,input_file_path4,input_file_path5,input_file_path6,prefix)\n",
    "\n",
    "# 假设 base_dir 是你的文件夹路径\n",
    "base_dir='./最终数据处理'\n",
    "process_files_with_same_prefix(base_dir)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 计算用户反馈"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import os\n",
    "import glob\n",
    "import numpy as np\n",
    "import pandas as pd\n",
    "import ast \n",
    "import statistics\n",
    "from datetime import datetime \n",
    "\n",
    "def get_prefix_from_path(file_path):\n",
    "    if not file_path:\n",
    "        return 'default'\n",
    "\n",
    "    base_name = os.path.splitext(os.path.basename(file_path))[0]\n",
    "    parts = base_name.split('_')\n",
    "    \n",
    "    if len(parts) >= 2:\n",
    "        return '_'.join(parts[:2])\n",
    "    else:\n",
    "        return base_name\n",
    "\n",
    "def feedback(input_file_path1,input_file_path2,input_file_path3,input_file_path4,input_file_path5,input_file_path6,input_file_path7,prefix):\n",
    "\n",
    "    df=pd.read_csv('feedback.csv')\n",
    "    df=pd.DataFrame(df)\n",
    "\n",
    "    data_part = pd.read_csv(input_file_path1)['指标值'] if input_file_path1 else np.zeros(300, dtype=int)\n",
    "    data_attention = pd.read_csv(input_file_path2)['指标值'] if input_file_path2 else np.zeros(300, dtype=int)\n",
    "    data_new = pd.read_csv(input_file_path3)['指标值'] if input_file_path3 else np.zeros(300, dtype=int)\n",
    "    data_comment = pd.read_csv(input_file_path4)['指标值'] if input_file_path4 else np.zeros(300, dtype=int)\n",
    "    data_stars = pd.read_csv(input_file_path5)['指标值'] if input_file_path5 else np.zeros(300, dtype=int)\n",
    "    data_fork = pd.read_csv(input_file_path6)['指标值'] if input_file_path6 else np.zeros(300, dtype=int)\n",
    "    data_closed = pd.read_csv(input_file_path7)['指标值'] if input_file_path7 else np.zeros(300, dtype=int)\n",
    "    \n",
    "    s_closed=[]\n",
    "    s_new=[]\n",
    "    s_attention=[]\n",
    "    s_stars=[]\n",
    "    s_fork=[]\n",
    "    for i in range(len(data_comment)) :\n",
    "        if data_comment[i]!=0:\n",
    "            s_closed.append(data_closed[i]/data_comment[i])\n",
    "            s_new.append(data_new[i]/data_comment[i])\n",
    "        else:\n",
    "            s_closed.append(0)\n",
    "            s_new.append(0)\n",
    "\n",
    "    avg1=np.mean(s_closed)\n",
    "    avg2=np.mean(s_new)\n",
    "\n",
    "    for i in range(len(data_part)):\n",
    "        if data_part[i]!=0:\n",
    "            s_attention.append(data_attention[i]/data_part[i])\n",
    "        else:\n",
    "            s_attention.append(0)\n",
    "    \n",
    "    for i in range(len(data_attention)):\n",
    "        if data_attention[i]!=0:\n",
    "            s_stars.append(data_stars[i]/data_attention[i])\n",
    "            s_fork.append(data_fork[i]/data_attention[i])\n",
    "        else:\n",
    "            s_stars.append(0)\n",
    "            s_fork.append(0)\n",
    "\n",
    "    avg3=np.mean(s_attention)\n",
    "    avg4=np.mean(s_stars)\n",
    "    avg5=np.mean(s_fork)\n",
    "    final=avg1*1/9+avg2*2/9+avg3*1/3+avg4*1/6+avg5*1/6\n",
    "\n",
    "\n",
    "    # 获取仓库名\n",
    "    row_exists=(df['指标名称']==prefix).any()\n",
    "\n",
    "    if row_exists:\n",
    "        df.loc[df['指标名称'] == prefix, '指标值']=final*10\n",
    "\n",
    "    # 保存更改回 CSV 文件\n",
    "    df.to_csv('feedback.csv', index=False)\n",
    "\n",
    "def get_prefix_and_rest(filename):\n",
    "\n",
    "    base_name = os.path.basename(filename)\n",
    "    # 分离文件名和扩展名\n",
    "    name_part, ext_part = os.path.splitext(base_name) \n",
    "    # 按下划线分割文件名部分，并确保至少有两个'_'\n",
    "    parts = name_part.split('_')\n",
    "\n",
    "    if len(parts) > 1:\n",
    "        # 获取前两个'_'之间的部分作为前缀\n",
    "        prefix = '_'.join(parts[:2])\n",
    "        # 剩余部分加上原始扩展名作为后缀\n",
    "        rest = '_'.join(parts[2:]) + ext_part if len(parts) > 2 else ext_part\n",
    "    else:\n",
    "        # 如果没有足够的'_'，则返回整个文件名作为前缀，空字符串作为后缀\n",
    "        prefix = name_part\n",
    "        rest = ext_part\n",
    "    \n",
    "    return prefix, rest\n",
    "\n",
    "def process_files_with_same_prefix(base_dir):\n",
    "    # 定义需要查找的文件后缀\n",
    "    file_suffixes = [\n",
    "        'participants.csv','attention.csv','issues_new.csv',\n",
    "        'issue_comments.csv','stars.csv','technical_fork.csv','issues_closed.csv'\n",
    "    ]\n",
    "    \n",
    "    # 获取所有csv文件\n",
    "    all_files = glob.glob(os.path.join(base_dir, '*.csv'))\n",
    "    # 创建一个字典来存储每个前缀对应的文件路径列表\n",
    "    files_dict = {}\n",
    "    \n",
    "    for file in all_files:\n",
    "        \n",
    "        # 获取仓库和后缀的部分作为前缀\n",
    "        prefix, suffix = get_prefix_and_rest(os.path.basename(file))\n",
    "        \n",
    "        key = next((s for s in file_suffixes if s==suffix), None)\n",
    "        if key:  # prefix是仓库名，key是文件后缀匹配，file是路径\n",
    "            if prefix not in files_dict:\n",
    "                files_dict[prefix] = {}\n",
    "            files_dict[prefix][key] = file\n",
    "    # 遍历字典并调用activity函数\n",
    "    for prefix, paths in files_dict.items():\n",
    "        # 调用 activity 函数，传递对应前缀的所有文件路径\n",
    "        input_file_path1=paths.get('participants.csv')\n",
    "        input_file_path2=paths.get('attention.csv')\n",
    "        input_file_path3=paths.get('issues_new.csv')\n",
    "        input_file_path4=paths.get('issue_comments.csv')\n",
    "        input_file_path5=paths.get('stars.csv')\n",
    "        input_file_path6=paths.get('technical_fork.csv')\n",
    "        input_file_path7=paths.get('issues_closed.csv')\n",
    "        feedback(input_file_path1,input_file_path2,input_file_path3,input_file_path4,input_file_path5,input_file_path6,input_file_path7,prefix)\n",
    "\n",
    "# 假设 base_dir 是你的文件夹路径\n",
    "base_dir='./最终数据处理'\n",
    "process_files_with_same_prefix(base_dir)"
   ]
  }
 ],
 "metadata": {
  "language_info": {
   "name": "python"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
